#include <OpenNetwork/OpenNetwork.h>

#include <iostream>

using namespace std;
using namespace onet;

//! Settings
static EPortType portType = EPT_TransmissionControlProtocol;
static u32 LENGTH = 2284;

//! Stat variables
bool done = false;
PeerID id = -1;

class SendCallback : public INetworkCallback
{
    virtual void onPeerConnect(const PeerID id_)
    {
        cout << getLocalTime() << " : Connected" << endl;

        id = id_;
    }
};

class ReceiveCallback : public INetworkCallback
{
    virtual void onMessageReceived(const PeerID id, u8 type, u32 length, c8* data, bool reliable)
    {
        done = true;

        if(length == LENGTH)
            cout << getLocalTime() << " : Received correct length" << endl;
    }
};

int main()
{
    //! Initialize sender, receiver and their callbacks
    SendCallback sendCallback;
    ReceiveCallback receiveCallback;

    INetworkPort* sender = createNetworkPort(portType, &sendCallback, 1,  51000, false, false);
    INetworkPort* receiver = createNetworkPort(portType, &receiveCallback, 1,  50000, true,false);

    cout << getLocalTime() << " : Initializing" << endl;

    if(!sender->init() || !receiver->init())
        cout << "Error!" << endl;

    else
    {
        cout << getLocalTime() << " : Connecting" << endl;

        //! Connect and loop until connected
        sender->connect(createAddressFromURL("localhost", 50000));

        while(id == -1)
        {
            receiver->work();
            sender->work();
        }

        //! Allocate a string we want to send
        c8 *someChars = new c8[LENGTH];

        cout << getLocalTime() << " : Sending..." << endl;

        //! sending
        sender->send(id, EMT_Custom+1, LENGTH, someChars, false);

        u32 time = getLocalTime();

        while(!done)
        {
            sender->work();
            receiver->work();
        }

        //! Print some statistics
        //! But milliseconds are a bit too big for local traffic
        //! Because of that you should use big chunks
        cout << getLocalTime() << " : Done." << endl;
        cout << "----------------------" << endl;
        cout << "Sending took " << f64(getLocalTime() - time)/1000 << " seconds" << endl;

        //! Clean up
        delete []someChars;
    }

    delete sender;
    delete receiver;

    return 1;
}
